home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
255_01
/
gpball.asm
< prev
next >
Wrap
Assembly Source File
|
1988-03-28
|
18KB
|
518 lines
page 80,132
page
;
; EGA Graphic Primitive for Turbo Pascal 3.01A, Version 01MAR86.
; (C) 1986 by Kent Cedola, 2015 Meadow Lake Ct., Norfolk, VA, 23518
;
; The algorithm for drawing a circle (below) was from an article in
; Dr. Dobb's Journal, December 1983, pp. 19 by Michael T. Enright.
;
; I converted it from BASIC source (from above) to assembler for high
; speed plotting and added color/shading fill and clipping code.
;
radius equ 4
xcoor1 equ -2 ; X coordinate (left half)
xcoor2 equ -4 ; X coordinate (right half)
ycoor1 equ -6 ; Location of Y graphic row, contains
ycoor2 equ -8 ; ... row byte offset.
xc equ -10
yc equ -12
xd equ -14 ; Long integer (32 bits)
yd equ -18 ; Long integer (32 bits)
zx equ -22 ; Long integer (32 bits)
zy equ -26 ; Long integer (32 bits)
tx equ -30 ; Long integer (32 bits)
ty equ -34 ; Long integer (32 bits)
tb equ -38 ; Long integer (32 bits)
er equ -42 ; Long integer (32 bits)
atx equ -46 ; Long integer (32 bits)
aty equ -50 ; Long integer (32 bits)
atb equ -54 ; Long integer (32 bits)
xf1 equ -58
xf2 equ -60
yf1 equ -62
yf2 equ -64
needed equ 68 ; Amount of temporary space needed
dgroup group _data
_data segment word public 'data'
assume ds:dgroup
extrn _gdtype:byte
extrn _gdmaxcol:word,_gdmaxrow:word
extrn _gdcolor:byte,_gdmerge:byte,_gdaspc1:word,_gdaspc2:word
extrn _gdcur_x:word,_gdcur_y:word
extrn _gdwd_x1:word,_gdwd_x2:word,_gdwd_x3:word
extrn _gdwd_y1:word,_gdwd_y2:word,_gdwd_y3:word
extrn _gdvw_x1:word,_gdvw_x2:word,_gdvw_x3:word
extrn _gdvw_y1:word,_gdvw_y2:word,_gdvw_y3:word
extrn _gdshade:word
extrn _gdc_flg:byte,_gds_flg:byte,_gdw_flg:byte
_data ends
_text segment byte public 'code'
assume cs:_text,ds:dgroup
public _gpball
_gpball proc near
push bp
mov bp,sp
sub sp,needed ; Reserve space for temp. variables
push si
push di
mov _GDC_FLG,2 ; Set clipping flag
; Compute AE = R (save in BX for later)
mov ax,[bp+radius] ; Load user specified radius
or ax,ax ; If radius is zero, make it 1
jnz notzero ;
inc ax ;
notzero:
mov bx,ax ; Copy to BX (AX used later)
mov ax,_GDCUR_X
sub ax,bx
cmp ax,_GDVW_X2
jbe next1
jmp theend
next1:
mov [bp+xc],ax
add ax,bx
add ax,bx
cmp ax,_GDVW_X1
jae next2
jmp theend
next2:
; Compute BE = (R * _GDASPC1 / _GDASPC2) (save in DX for later)
mov ax,bx ; Start with R (AE above)
mul _GDASPC1 ; Compute the real Y radius from the
div _GDASPC2 ; the defined screen aspects
mov dx,ax ; Copy to DX (temp save area)
; Compute the Y coordinate graphic row offset.
mov cx,_GDCUR_Y ; Compute the upper and lower row for
sub cx,ax ; line clipping logic
cmp cx,_GDVW_Y2 ;
jbe next3
jmp theend
next3:
mov [bp+yc],cx
mov [bp+yf1],cx ; ...
add cx,ax ; ...
add cx,ax ; ...
cmp cx,_GDVW_Y1
jae next4
jmp theend
next4:
mov [bp+yf2],cx ; ...
mov _GDC_FLG,0 ; Clear clipping flag
shl ax,1 ; Compute the graphic segment offset
shl ax,1 ; for the Y radius length
add ax,dx ; ...
mov si,ax ; Copy to SI (temp save area)
mov ax,_GDCUR_Y ; Compute the graphic segment offset
shl ax,1 ; for the current row
shl ax,1 ; ... = A000 + (80 * Y) / 16;
add ax,_GDCUR_Y ; ...
add ax,0A000h ; ...
sub ax,si ; Init the top and bottow y coordinates
mov [bp+ycoor1],ax ; ...
add ax,si ; ...
add ax,si ; ...
mov [bp+ycoor2],ax ; ...
; Compute the X coordinate graphic bit offset.
mov ax,_GDCUR_X ; Compute the column byte offset
mov [bp+xf1],ax ; Save the left and right column numbers
mov [bp+xf2],ax ; for clipping logic
; Compute XD = BE * BE
mov cx,dx ; Save BE for later (in CX)
mov ax,dx ; Must use AX for multiply
mul dx ; BE * BE (AX * DX)
mov [bp+xd],ax ; Save XD
mov [bp+xd-2],dx ; ...
; Compute DX = 2 * BE * BE (or XD * 2)
shl ax,1 ; Long shift left for multiply
rcl dx,1 ; ...
mov [bp+zx],ax ; Save DX
mov [bp+zx-2],dx ; ...
; Compute DY = 2 * AE * AE
mov ax,bx ; Move current AE to AX
mul bx ; ... (AE * AE)
push dx ; Save the value (AE * AE) for later
push ax ; ...
shl ax,1 ; Compute AE * AE * 2 (shift left)
rcl dx,1 ; ...
mov [bp+zy],ax ; Save DY
mov [bp+zy-2],dx ; ...
; Compute YD = (2 * BE - 1) * AE * AE
pop ax
shl cx,1 ; Compute BE * 2
dec cx ; Compute BE * 2 - 1
mul cx ; Compute (BE * 2 - 1) * AE
mov [bp+yd],ax ; Save what we have so far
mov [bp+yd-2],dx ; ...
pop ax ; Compute (BE * 2 - 1) * AE * AE
mul cx ; ...
add [bp+yd-2],ax ; ...
; Compute ER = 0
xor ax,ax ; Clear AX to clear ER
mov [bp+er],ax ; ...
mov [bp+er-2],ax ; ...
; Setup the EGA to perform graphics
mov dx,03CEh ; Load EGA graphic controller port addr.
mov ah,_GDMERGE ; Load current merge setting
mov al,3 ; Merge register is number three
out dx,ax ; Set the EGA's merge register
mov ax,0205h ; Load write mode number two
out dx,ax ; Set the EGA's mode register
mov al,8 ; Load the mask register number
out dx,al ; Just postion EGA's controller to it
call plotpnts ; Plot the first set of points
next_x:
mov cx,-1
mov ax,[bp+er] ; Compute TX = ER + XD
mov dx,[bp+er-2] ; ...